package com.loe.ktui.custom

import android.content.Context
import android.content.res.TypedArray
import android.graphics.Canvas
import android.graphics.Paint
import android.graphics.Typeface
import android.graphics.drawable.ColorDrawable
import android.graphics.drawable.Drawable
import android.util.AttributeSet
import android.view.MotionEvent
import android.view.View
import android.view.ViewGroup
import androidx.core.content.res.getDimensionOrThrow
import com.loe.ktui.*
import com.loe.ktui.ktPx
import com.loe.ktui.UiGroup
import com.loe.ktui.UiView
import com.loe.ktui.util.KtCornerProvider
import com.loe.ktui.util.UiShape

open class UiLetterBar(id: String? = null) : UiView(id)
{
    var textColor: Int? = null
    var selectTextColor: Int? = null
    var textSize: Any? = null
    var bold: Boolean? = null
    var chars: String? = null

    var selectBg: Any? = null
    var selectBgRes: Int? = null

    var onLetterChanged: (KtLetterBar.(s: String, position: Int) -> Unit)? = null
    fun onLetterChanged(onLetterChanged: KtLetterBar.(s: String, position: Int) -> Unit)
    {
        this.onLetterChanged = onLetterChanged
    }

    open fun initUI(context: Context, view: KtLetterBar)
    {
        val bg = this.bg
        val bgRes = this.bgRes
        this.bg = null
        this.bgRes = null
        super.initUI(context, view)

        textColor?.let { view.textColor = it }
        selectTextColor?.let { view.selectTextColor = it }
        textSize?.let { view.textSize = it.dist }
        bold?.let { view.bold = it }
        chars?.let { view.chars = it }

        onLetterChanged?.let { onLetterChanged ->
            view.setOnLetterChanged()
            { s, position ->
                view.onLetterChanged(s, position)
            }
        }

        bg?.let {
            when (it)
            {
                is UiShape ->
                {
                    view.normalBg = it.createDrawable()
                    view.background = view.normalBg
                }
                is Int ->
                {
                    view.normalBg = ColorDrawable(it)
                    view.background = view.normalBg
                }
                else ->
                {
                    context.getUrlDrawable(it.toString())
                    {
                        view.normalBg = it
                        view.background = view.normalBg
                    }
                }
            }
        }
        bgRes?.let {
            view.setBackgroundResource(it)
            view.normalBg = view.background
        }
        selectBg?.let {
            when (it)
            {
                is UiShape -> view.selectBg = it.createDrawable()
                is Int -> view.selectBg = ColorDrawable(it)
                else -> context.getUrlDrawable(it.toString()) { view.selectBg = it }
            }
        }
        selectBgRes?.let { view.selectBg = context.resources.getDrawable(it, context.theme) }
    }

    /** 创建view */
    override fun createView(context: Context, parent: ViewGroup?): KtLetterBar
    {
        return KtLetterBar(context).also()
        {
            initUI(context, it)
            addToParent(parent, it)
        }
    }
}

fun Any.ui_LetterBar(id: String? = null, block: (UiLetterBar.() -> Unit)? = null): UiLetterBar
{
    val ui = UiLetterBar(id)
    block?.let { ui.it() }
    if (this is UiGroup) addChild(ui)
    return ui
}

class KtLetterBar : View
{
    constructor(context: Context) : super(context)
    {
        initXML()
    }

    constructor(context: Context, attrs: AttributeSet) : super(context, attrs)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.KtLetterBar))
    }

    constructor(context: Context, attrs: AttributeSet, defStyleAttr: Int) : super(context, attrs, defStyleAttr)
    {
        initXML(context.obtainStyledAttributes(attrs, R.styleable.KtLetterBar, defStyleAttr, 0))
    }

    private fun initXML(typedArray: TypedArray? = null)
    {
        mPaint = Paint(Paint.ANTI_ALIAS_FLAG)
        mPaint.isAntiAlias = true
        isClickable = true
        normalBg = background

        typedArray?.let()
        {
            if (it.hasValue(R.styleable.KtLetterBar_kt_corner))
            {
                val corner = it.getDimensionOrThrow(R.styleable.KtLetterBar_kt_corner).toInt()
                val cornerDirect =  KtDirects[it.getInt(R.styleable.KtLetterBar_kt_cornerDirect, 4)]

                outlineProvider = KtCornerProvider(corner, cornerDirect, this)
            }

            textColor = it.getColor(R.styleable.KtLetterBar_kt_textColor, textColor)
            selectTextColor = it.getColor(R.styleable.KtLetterBar_kt_selectTextColor, selectTextColor)
            textSize = it.getDimensionPixelOffset(R.styleable.KtLetterBar_kt_textSize, textSize)
            bold = it.getBoolean(R.styleable.KtLetterBar_kt_bold, bold)
            chars = it.getString(R.styleable.KtLetterBar_kt_chars) ?: chars
            if(it.hasValue(R.styleable.KtLetterBar_kt_bg))
            {
                background = it.getDrawable(R.styleable.KtLetterBar_kt_bg)
                normalBg = background
            }
            selectBg = it.getDrawable(R.styleable.KtLetterBar_kt_selectBg)

            it.recycle()
        }
    }

    private val map: HashMap<String, Int> by lazy { HashMap() }

    // 字母列表颜色
    var textColor = 0xff666666.toInt()
        set(value)
        {
            field = value
            invalidate()
        }

    // 被选中的字母颜色
    var selectTextColor = 0xffff0000.toInt()
        set(value)
        {
            field = value
            invalidate()
        }

    // 字母字体大小
    var textSize = ktPx(14.0)
        set(value)
        {
            field = value
            mPaint.textSize = value.toFloat()
            invalidate()
        }

    // 是否是粗体字母
    var bold = false
        set(value)
        {
            field = value
            mPaint.typeface = if (value) Typeface.DEFAULT_BOLD else Typeface.DEFAULT
            invalidate()
        }

    // 背景
    var normalBg: Drawable? = null

    // 选中时的背景
    var selectBg: Drawable? = null

    // 默认字符
    var chars = "ABCDFGHJKLMNPQRSTWXYZ"
        set(value)
        {
            field = value
            invalidate()
        }

    /**********************************************************************************************/

    // 宽度
    private var mWidth = 0

    // 去除padding后的高度
    private var mHeight = 0

    // 选中的字母是第几个
    private var mChoose = -1

    private lateinit var mPaint: Paint

    override fun onSizeChanged(w: Int, h: Int, oldw: Int, oldh: Int)
    {
        super.onSizeChanged(w, h, oldw, oldh)
        mHeight = h - paddingTop - paddingBottom
        mWidth = w
    }

    override fun onDraw(canvas: Canvas)
    {
        var i = 0
        val len = chars.length
        while (i < len)
        {
            val letter = chars.substring(i, i + 1)
            val letterWidth = mPaint.measureText(letter)
            mPaint.color = if (i == mChoose) selectTextColor else textColor
            val xPos = (mWidth - letterWidth) / 2
            val yPos = mHeight / chars.length * (i + 0.5f) + paddingTop
            canvas.drawText(letter, xPos, yPos, mPaint)
            i++
        }
        super.onDraw(canvas)
    }

    override fun dispatchTouchEvent(event: MotionEvent): Boolean
    {
        val y = event.y
        // 点击y坐标
        val oldChoose = mChoose
        mChoose = when
        {
            y < paddingTop ->
            {
                0
            }
            y > mHeight + paddingTop ->
            {
                chars.length - 1
            }
            else ->
            {
                // 点击y坐标所占总高度的比例*b数组的长度就等于点击b中的个数.
                ((y - paddingTop) / mHeight * chars.length).toInt()
            }
        }
        when (event.action)
        {
            MotionEvent.ACTION_UP ->
            {
                mChoose = -1
                background = normalBg
                if (oldChoose != mChoose && mChoose != -1)
                {
                    onLetterChanged?.invoke(chars.substring(mChoose, mChoose + 1), mChoose)
                    background = selectBg
                }
            }
            else -> if (oldChoose != mChoose && mChoose != -1)
            {
                onLetterChanged?.invoke(chars.substring(mChoose, mChoose + 1), mChoose)
                background = selectBg
            }
        }
        invalidate()
        return super.dispatchTouchEvent(event)
    }

    fun setTitle(c: String, index: Int)
    {
        map[c] = index
    }

    fun getTitleIndex(c: String): Int?
    {
        return map[c]
    }

    private var onLetterChanged: ((s: String, position: Int) -> Unit)? = null

    fun setOnLetterChanged(onLetterChanged: (s: String, position: Int) -> Unit)
    {
        this.onLetterChanged = onLetterChanged
    }
}